﻿using JWTWebApi.Utils;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Serilog;
using System.Text;

namespace JWTWebApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // 从配置文件读取 Serilog 配置
            IConfigurationRoot configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
                .Build();

            // 使用配置文件初始化 Serilog
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .CreateLogger();

            try
            {
                Log.Information("应用程序启动中...");

                WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

                // 使用 Serilog 作为日志提供程序
                builder.Host.UseSerilog();

                // 添加单一实例服务，用于读取配置文件
                builder.Services.AddSingleton(new AppSettings(builder.Configuration));
                // 添加控制器服务
                builder.Services.AddControllers().AddNewtonsoftJson(options =>
                {
                    // 全局配置日期格式
                    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                });
                // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
                // 添加Swagger服务
                builder.Services.AddEndpointsApiExplorer();
                // 添加Swagger生成器
                builder.Services.AddSwaggerGen();

                // 添加CORS策略
                builder.Services.AddCors(options =>
                {
                    options.AddPolicy("AllowSpecificOrigin", policy =>
                    {
                        string[] origins = builder.Configuration.GetSection("CorsAccessorSettings:AllowOrigins").Get<string[]>() ?? Array.Empty<string>();
                        policy.WithOrigins(origins) // 允许指定的源
                              .AllowAnyHeader() // 允许任何请求头
                              .AllowAnyMethod(); // 允许任何请求方法
                    });
                });

                SymmetricSecurityKey signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettings.GetConfig<string>("Jwt:SecretKey")));

                // 添加 JWT 认证服务
                builder.Services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                }).AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = builder.Configuration["Jwt:Issuer"],
                        ValidAudience = builder.Configuration["Jwt:Audience"],
                        IssuerSigningKey = signingKey
                    };
                });

                // 添加授权服务
                builder.Services.AddAuthorization();

                // 构建应用程序
                WebApplication app = builder.Build();

                // 配置HTTP请求管道
                // 如果当前环境是开发环境，则启用Swagger接口文档和UI界面
                if (app.Environment.IsDevelopment())
                {
                    app.UseSwagger(); // 启用Swagger接口文档
                    app.UseSwaggerUI(); // 启用Swagger UI界面
                }

                // 强制将所有HTTP请求重定向为HTTPS请求
                // app.UseHttpsRedirection();

                // 启用路由中间件，路由系统的“大脑”，负责解析请求路径并选择终结点
                app.UseRouting();

                // 启用CORS（跨域资源共享），允许指定的跨域请求
                app.UseCors("AllowSpecificOrigin");

                // 启用认证中间件，处理请求中的身份验证逻辑（如JWT认证）
                app.UseAuthentication();
                // 启用授权中间件，在认证成功后检查用户是否有权限访问特定资源
                app.UseAuthorization();

                // 启用默认文件中间件，用于提供静态文件服务（如index.html作为默认文件）
                app.UseDefaultFiles();
                // 启用静态文件中间件，用于提供静态资源文件（如CSS、JS、图片等）
                app.UseStaticFiles();
                // 映射控制器路由，路由系统的“执行者”，将控制器的动作方法绑定到具体的路由模板
                app.MapControllers();

                // 启动应用程序，开始监听HTTP请求
                app.Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "应用程序启动失败");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
    }
}
